package common.Utils;

import java.lang.reflect.Field;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class CommonUtils 
{
	public static Gson createGsonInstance(HttpServletResponse response)
	{
		response.setContentType("application/json"); 
		GsonBuilder builder = new GsonBuilder();
		builder.registerTypeAdapter(UUID.class, new UUIDDeserializer()); 
		
		return builder.create();
	}
	
	private static boolean assertClassHierarchy(Object oldItem, Object newItem)
	{
		boolean belongsClassHierarchy = (oldItem.getClass() == newItem.getClass());
		if(!belongsClassHierarchy && (oldItem.getClass().getSuperclass() != Object.class))
			belongsClassHierarchy = (oldItem.getClass().getSuperclass() == newItem.getClass());
		
		return belongsClassHierarchy;
	}
	
	public static void updateItem(Object oldItem, Object newItem)
	{
		if((oldItem != null && newItem != null) && assertClassHierarchy(oldItem, newItem))
		{
			for(Field field : newItem.getClass().getDeclaredFields())
				try
				{
					//TODO: Check if this is ok or if it can be 'reused' with the assertClassHierarchy method...
					Field originalField = (oldItem.getClass().getSuperclass() == newItem.getClass()) ? oldItem.getClass().getSuperclass().getDeclaredField(field.getName())
							: oldItem.getClass().getDeclaredField(field.getName()); 
					
					field.setAccessible(true);
					originalField.setAccessible(true);
					
					if(field.get(newItem) != null)
						originalField.set(oldItem, field.get(newItem));
					
					field.setAccessible(false);
					originalField.setAccessible(false);
					
				}
				catch(Exception e){}	
		}
	}
	
	public static boolean hasStringChange(Object original, Object other)
	{
		boolean hasChange = false;
		
		if((original != null && other != null) && (other.getClass() == original.getClass()))
		{
			for(Field field : other.getClass().getDeclaredFields())
				if(field.getType() == String.class)
					try
					{
						Field originalField = original.getClass().getDeclaredField(field.getName());
						field.setAccessible(true);
						originalField.setAccessible(true);
						
						hasChange = !(originalField.get(original).equals(field.get(other)));
						
						field.setAccessible(false);
						originalField.setAccessible(false);
						
						if(hasChange)
							break;
					}
					catch(Exception e){}	
		}
		
		return hasChange;
	}
}
